package com.chengyu.core.util;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;



import java.io.Serializable;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;

/**
 * @title  redis工具类
 * @author LeGreen
 * @date   2021/1/6
 */
@Service
public class RedisUtil {

	private static final String COMMON_KEY = "hbcarbon-";

	@Resource
	private RedisTemplate<String, Object> redisTemplate;

	/**
	 * 设置缓存过期时间
	 * @param key 缓存Key
	 * @param timeout 过期时间
	 * @param unit 单位(默认为秒-TimeUnit.SECONDS)
	 */
	public void expire(String key, long timeout, TimeUnit unit) {
		key = COMMON_KEY+key;
		redisTemplate.expire(key, timeout, unit == null ? TimeUnit.SECONDS : unit);
	}

	/**
	 * 设置缓存
	 * @param key 缓存Key
	 * @param value 缓存值
	 */
	public void setRedisValue(String key, Object value) {
		setRedisValue(key, value, null, null);
	}

	/**
	 * 设置缓存
	 * @param key 缓存Key
	 * @param value 缓存值
	 * @param timeout 过期时间
	 * @param unit 单位(默认为秒-TimeUnit.SECONDS)
	 */
	public void setRedisValue(String key, Object value, Long timeout, TimeUnit unit) {
		key = COMMON_KEY+key;
		if(timeout == null || timeout <= 0) {
			redisTemplate.opsForValue().set(key, value);
		} else {
			redisTemplate.opsForValue().set(key, value, timeout, unit == null ? TimeUnit.SECONDS : unit);
		}
	}

	/**
	 * 获取对象缓存(String)
	 * @param key 缓存Key
	 * @return
	 */
	public Object getRedisValue(String key) {
		key = COMMON_KEY+key;
		return redisTemplate.opsForValue().get(key);
	}

	/**
	 * 删除缓存
	 * @param keys 要删除的缓存keys
	 */
	public void delete(String ... keys) {
		if(keys == null || keys.length <= 0) {
			return;
		}

		List<String> keyList = new ArrayList<>();
		for(String key : keys) {
			key = COMMON_KEY+key;
			keyList.add(key);
		}
		redisTemplate.delete(keyList);
	}

	/**
	 * 删除缓存
	 * @param keys 要删除的缓存keys
	 */
	public void deletePattern(String ... keys) {
		if(keys == null || keys.length <= 0) {
			return;
		}

		for(String key : keys) {
			key = COMMON_KEY+key;
			redisTemplate.delete(redisTemplate.keys(key+"*"));
		}
	}













	/**
	 * 写入缓存
	 * @param key
	 * @param value
	 * @return
	 */
	public boolean set(final String key, Object value) {
		boolean result = false;
		try {
			ValueOperations<String, Object> operations = redisTemplate.opsForValue();
			operations.set(key, value);
			result = true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}
	/**
	 * 写入缓存设置时效时间
	 * @param key
	 * @param value
	 * @return
	 */
	public boolean set(final String key, Object value, Long expireTime ,TimeUnit timeUnit) {
		boolean result = false;
		try {
			ValueOperations<String, Object> operations = redisTemplate.opsForValue();
			operations.set(key, value);
			redisTemplate.expire(key, expireTime, timeUnit);
			result = true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}
	/**
	 * 批量删除对应的value
	 * @param keys
	 */
	public void remove(final String... keys) {
		for (String key : keys) {
			remove(key);
		}
	}
	/**
	 * 批量删除key
	 * @param pattern
	 */
	public void removePattern(final String pattern) {
		Set<String> keys = redisTemplate.keys(pattern);
		if (keys.size() > 0){
			redisTemplate.delete(keys);
		}
	}
	/**
	 * 删除对应的value
	 * @param key
	 */
	public void remove(final String key) {
		if (exists(key)) {
			redisTemplate.delete(key);
		}
	}
	/**
	 * 判断缓存中是否有对应的value
	 * @param key
	 * @return
	 */
	public boolean exists(final String key) {
		return redisTemplate.hasKey(key);
	}
	/**
	 * 读取缓存
	 * @param key
	 * @return
	 */
//	public Object get(final String key) {
//		Object result = null;
//		ValueOperations<String, Object> operations = redisTemplate.opsForValue();
//		result = operations.get(key);
//		return result;
//	}
	/**
	 * 读取缓存
	 *
	 * @param key 键
	 * @return T
	 */
	@SuppressWarnings("unchecked")
	public <T> T get(String key) {
		return key == null ? null : (T) redisTemplate.opsForValue().get(key);
	}

	/**
	 * 哈希 添加
	 * @param key
	 * @param hashKey
	 * @param value
	 */
	public void hmSet(String key, Object hashKey, Object value){
		HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
		hash.put(key,hashKey,value);
	}
	/**
	 * 哈希获取数据
	 * @param key
	 * @param hashKey
	 * @return
	 */
	public Object hmGet(String key, Object hashKey){
		HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
		return hash.get(key,hashKey);
	}
	/**
	 * 列表添加
	 * @param k
	 * @param v
	 */
	public void lPush(String k,Object v){
		ListOperations<String, Object> list = redisTemplate.opsForList();
		list.rightPush(k,v);
	}
	/**
	 * 列表获取
	 * @param k
	 * @param l
	 * @param l1
	 * @return
	 */
	public List<Object> lRange(String k, long l, long l1){
		ListOperations<String, Object> list = redisTemplate.opsForList();
		return list.range(k,l,l1);
	}
	/**
	 * 集合添加
	 * @param key
	 * @param value
	 */
	public void add(String key,Object value){
		SetOperations<String, Object> set = redisTemplate.opsForSet();
		set.add(key,value);
	}
	/**
	 * 集合获取
	 * @param key
	 * @return
	 */
	public Set<Object> setMembers(String key){
		SetOperations<String, Object> set = redisTemplate.opsForSet();
		return set.members(key);
	}
	/**
	 * 有序集合添加
	 * @param key
	 * @param value
	 * @param scoure
	 */
	public void zAdd(String key,Object value,double scoure){
		ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
		zset.add(key,value,scoure);
	}
	/**
	 * 有序集合获取
	 * @param key
	 * @param scoure
	 * @param scoure1
	 * @return
	 */
	public Set<Object> rangeByScore(String key,double scoure,double scoure1){
		ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
		return zset.rangeByScore(key, scoure, scoure1);
	}

	/**
	 * 哈希删除
	 *
	 * @param key     键 不能为null
	 * @param hashKey 项 不能为null
	 */
	public void hmDelete(String key, Object hashKey) {
		redisTemplate.opsForHash().delete(key, hashKey);
	}
	/**
	 * 哈希数量
	 *
	 * @param key 键
	 * @return 键下的数量
	 */
	public Long getHashSize(String key) {
		return redisTemplate.opsForHash().size(key);
	}

	// ===============================list=================================
	/**
	 * 向一张hash表中放入数据,如果不存在将创建
	 *
	 * @param key   键
	 * @param item  项
	 * @param value 值
	 * @return true 成功 false失败
	 */
	public boolean hset(String key, String item, Object value) {
		try {
			redisTemplate.opsForHash().put(key, item, value);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	/**
	 * 哈希获取数据 HashGet
	 *
	 * @param key  键 不能为null
	 * @param item 项 不能为nul
	 * @return 值
	 */
	public Object hget(String key, String item) {
		return redisTemplate.opsForHash().get(key, item);
	}



}
